<?php

declare( strict_types = 1 );

namespace App\Common\Model\Base\DataUnit;

use App\Common as com;
use App\Common\Model\Base as nameBase;
use App\Common\Model\Base\DataUnit as nameDataUnit;

class GetDataset extends nameDataUnit\Base {

	private array $getsInfo = [];

	/**
	 * 魔术方法->call
	 * @param string $name 方法名
	 * @param array $arguments 参数[]
	 * @return mixed
	 * @throws
	 */
	public function __call( string $name, array $arguments ) {
		// 取动作类型
		$action = substr( $name, 0, 3 );
		// 处理属性读写
		switch( $action ){
			case 'pre':
				return $this->__magicCallOfPre( $name, $arguments );
			default:
				throw com\Lib\Err\Exception::makeOfNew( '', com\Cla\Err\Code::$sysFunExecuteError );
		}
	}

	/**
	 * 魔术方法->call->get(处理属性读写)
	 * @param string $name 方法名
	 * @param array $arguments 参数
	 * @return mixed||Exception 返回数据(如无法处理则抛出异常:com\Cla\Err\Code::$sysDataErrorSeverity)
	 */
	protected function __magicCallOfPre( string $name, array $arguments ){
		// 取出属性名
		$propertyName = substr( $name, 3 );
		$propertyName = com\Lib\Fun\Str::parseName( $propertyName, 1, false );
		//
		if( ! array_key_exists( $propertyName, $this->getsInfo ) ){
			$defaultValue = $arguments[0] ?? null;
			$this->getsInfo[ $propertyName ] = $defaultValue;
		}
		//
		return $this;
	}

	/**
	 * @param bool $isAll 是否获取全部字段数据
	 * @return array|null [null]数据不存在
	 * @throws
	 */
	public function gets( bool $isAll = false ):?array {
		if( $isAll ){
			$getFields = array_keys( $this->getDataUnit()->getDataOperateData() );
		}else{
			$getFields = array_keys( $this->getsInfo );
		}
		//
		if( empty( $getFields ) ){
			throw com\Lib\Err\Exception::makeOfNew( '', com\Lib\Err\Code::$sysDataNotExist );
		}
		//
		$datas = $this->getDataUnit()->goDataset()->gets( $getFields );
		//
		$this->reset();
		//
		return $datas;
	}

	/**
	 * @param bool $isAll
	 * @return com\Lib\Utils\Helper\Array_|null
	 * @throws com\Lib\Err\BaseException\Throw_
	 */
	public function getsToArrayHelper( bool $isAll = false ):?com\Lib\Utils\Helper\Array_ {
		$datas = $this->gets( $isAll );
		if( $datas === null ){
			return null;
		}
		return com\Lib\Utils\Helper\Array_::makeOfNew( $datas );
	}

	/**
	 * @return array
	 */
	public function getsOrDefault( bool $isAll = false ):array {
		if( ! $isAll ){
			$defaultDatas = $this->getsInfo;
		}
		//
		$datas = $this->gets( $isAll );
		//
		if( $datas === null ){
			if( $isAll ){
				return $this->getDataUnit()->getDataOperateData();
			}else{
				return $defaultDatas;
			}

		}else{
			return $datas;
		}
	}

	/**
	 * 重置
	 * @return bool [true][必返]
	 */
	private function reset(  ):bool {
		$this->getsInfo = [];
		//
		return true;
	}

}
